#ifndef __LLDEBUG_EVENT_H__
#define __LLDEBUG_EVENT_H__

#include "dll_export.h"
#include "../cppx.luavm/LogData.h"
#include "../cppx.luavm/SourceManager.h"
#include <wx/event.h>

LUA_DEBUG_BEGIN

enum {
    //LLDEBUG_FRAMESIZE = 128,

    ID_MAINFRAME = wxID_HIGHEST + 2560,
    ID_WINDOWHOLDER,
    ID_SOURCEVIEW,
    ID_OUTPUTVIEW,
    ID_INTERACTIVEVIEW,
    ID_LOCALWATCHVIEW,
    ID_GLOBALWATCHVIEW,
    ID_REGISTRYWATCHVIEW,
    ID_ENVIRONWATCHVIEW,
    ID_STACKWATCHVIEW,
    ID_WATCHVIEW,
    ID_BACKTRACEVIEW,
};

_LUADBG_API extern const wxEventType wxEVT_DEBUG_END_DEBUG;
_LUADBG_API extern const wxEventType wxEVT_DEBUG_CHANGED_STATE;
_LUADBG_API extern const wxEventType wxEVT_DEBUG_UPDATE_SOURCE;
_LUADBG_API extern const wxEventType wxEVT_DEBUG_ADDED_SOURCE;
_LUADBG_API extern const wxEventType wxEVT_DEBUG_CHANGED_BREAKPOINTS;
_LUADBG_API extern const wxEventType wxEVT_DEBUG_OUTPUT_LOG;
_LUADBG_API extern const wxEventType wxEVT_DEBUG_OUTPUT_INTERACTIVEVIEW;
_LUADBG_API extern const wxEventType wxEVT_DEBUG_FOCUS_ERRORLINE;
_LUADBG_API extern const wxEventType wxEVT_DEBUG_FOCUS_BACKTRACELINE;

class _LUADBG_API wxDebugEvent : public wxEvent
{
public:
    /// EndDebug, ChangedBreakpointList event
    explicit wxDebugEvent(wxEventType type, int winid);

    /// ChangedState event
    explicit wxDebugEvent(wxEventType type, int winid, bool isBreak);

    /// UpdateSource event
    explicit wxDebugEvent(wxEventType type, int winid, const std::string &key, 
        int line, int updateCount, bool isRefreshOnly);

    /// FocusErrorLine event
    explicit wxDebugEvent(wxEventType type, int winid, const std::string &key, int line);

    /// FocusBacktraceLine event
    explicit wxDebugEvent(wxEventType type, int winid, const LuaBacktrace &bt);

    /// AddedSource event
    explicit wxDebugEvent(wxEventType type, int winid, const Source &source);

    /// OutputLog event
    explicit wxDebugEvent(wxEventType type, int winid, const LogData &logData);

    virtual ~wxDebugEvent();

    virtual wxEvent *Clone() const;

    /// Get the source object.
    const Source &GetSource() const;

    /// Get the backtrace object.
    const LuaBacktrace &GetBacktrace() const;

    /// Get identifier key of the source file.
    const std::string &GetKey() const;

    /// Get the number of line.
    int GetLine() const;

    /// Get the log type.
    const LogData &GetLogData() const;

    /// Get the count of 'update source'.
    int GetUpdateCount() const;

    /// Is the 'update source' intend to refresh only ?
    bool IsRefreshOnly() const;

    /// Is state breaking (stop running) ?
    bool IsBreak() const;

private:
    Source m_source;
    LuaBacktrace m_backtrace;
    std::string m_key;
    int m_line;
    LogData m_logData;
    int m_updateCount;
    bool m_isRefreshOnly;
    bool m_isBreak;
};

typedef void (wxEvtHandler::*wxDebugEventFunction)(wxDebugEvent &);

#define wxDebugEventHandler(func) \
    wxEVENT_HANDLER_CAST(wxDebugEventFunction, func)

#if !wxCHECK_VERSION(2, 5, 0)
#define EVT_DEBUG_END_DEBUG(id, fn)           DECLARE_EVENT_TABLE_ENTRY(wxEVT_DEBUG_END_DEBUG,           id, wxID_ANY, (wxObjectEventFunction)(wxEventFunction)(wxDebugEventFunction)(&fn), (wxObject *)NULL),
#define EVT_DEBUG_CHANGED_STATE(id, fn)       DECLARE_EVENT_TABLE_ENTRY(wxEVT_DEBUG_CHANGED_STATE,       id, wxID_ANY, (wxObjectEventFunction)(wxEventFunction)(wxDebugEventFunction)(&fn), (wxObject *)NULL),
#define EVT_DEBUG_UPDATE_SOURCE(id, fn)       DECLARE_EVENT_TABLE_ENTRY(wxEVT_DEBUG_UPDATE_SOURCE,       id, wxID_ANY, (wxObjectEventFunction)(wxEventFunction)(wxDebugEventFunction)(&fn), (wxObject *)NULL),
#define EVT_DEBUG_ADDED_SOURCE(id, fn)        DECLARE_EVENT_TABLE_ENTRY(wxEVT_DEBUG_ADDED_SOURCE,        id, wxID_ANY, (wxObjectEventFunction)(wxEventFunction)(wxDebugEventFunction)(&fn), (wxObject *)NULL),
#define EVT_DEBUG_CHANGED_BREAKPOINTS(id, fn) DECLARE_EVENT_TABLE_ENTRY(wxEVT_DEBUG_CHANGED_BREAKPOINTS, id, wxID_ANY, (wxObjectEventFunction)(wxEventFunction)(wxDebugEventFunction)(&fn), (wxObject *)NULL),
#define EVT_DEBUG_OUTPUT_LOG(id, fn)          DECLARE_EVENT_TABLE_ENTRY(wxEVT_DEBUG_OUTPUT_LOG,          id, wxID_ANY, (wxObjectEventFunction)(wxEventFunction)(wxDebugEventFunction)(&fn), (wxObject *)NULL),
#define EVT_DEBUG_FOCUS_ERRORLINE(id, fn)     DECLARE_EVENT_TABLE_ENTRY(wxEVT_DEBUG_FOCUS_ERRORLINE,     id, wxID_ANY, (wxObjectEventFunction)(wxEventFunction)(wxDebugEventFunction)(&fn), (wxObject *)NULL),
#define EVT_DEBUG_FOCUS_BACKTRACELINE(id, fn) DECLARE_EVENT_TABLE_ENTRY(wxEVT_DEBUG_FOCUS_BACKTRACELINE, id, wxID_ANY, (wxObjectEventFunction)(wxEventFunction)(wxDebugEventFunction)(&fn), (wxObject *)NULL),
#else
#define EVT_DEBUG_END_DEBUG(id, fn)           DECLARE_EVENT_TABLE_ENTRY(wxEVT_DEBUG_END_DEBUG,           id, wxID_ANY, (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxDebugEventFunction, &fn), (wxObject *)NULL),
#define EVT_DEBUG_CHANGED_STATE(id, fn)       DECLARE_EVENT_TABLE_ENTRY(wxEVT_DEBUG_CHANGED_STATE,       id, wxID_ANY, (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxDebugEventFunction, &fn), (wxObject *)NULL),
#define EVT_DEBUG_UPDATE_SOURCE(id, fn)       DECLARE_EVENT_TABLE_ENTRY(wxEVT_DEBUG_UPDATE_SOURCE,       id, wxID_ANY, (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxDebugEventFunction, &fn), (wxObject *)NULL),
#define EVT_DEBUG_ADDED_SOURCE(id, fn)        DECLARE_EVENT_TABLE_ENTRY(wxEVT_DEBUG_ADDED_SOURCE,        id, wxID_ANY, (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxDebugEventFunction, &fn), (wxObject *)NULL),
#define EVT_DEBUG_CHANGED_BREAKPOINTS(id, fn) DECLARE_EVENT_TABLE_ENTRY(wxEVT_DEBUG_CHANGED_BREAKPOINTS, id, wxID_ANY, (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxDebugEventFunction, &fn), (wxObject *)NULL),
#define EVT_DEBUG_OUTPUT_LOG(id, fn)          DECLARE_EVENT_TABLE_ENTRY(wxEVT_DEBUG_OUTPUT_LOG,          id, wxID_ANY, (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxDebugEventFunction, &fn), (wxObject *)NULL),
#define EVT_DEBUG_FOCUS_ERRORLINE(id, fn)     DECLARE_EVENT_TABLE_ENTRY(wxEVT_DEBUG_FOCUS_ERRORLINE,     id, wxID_ANY, (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxDebugEventFunction, &fn), (wxObject *)NULL),
#define EVT_DEBUG_FOCUS_BACKTRACELINE(id, fn) DECLARE_EVENT_TABLE_ENTRY(wxEVT_DEBUG_FOCUS_BACKTRACELINE, id, wxID_ANY, (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxDebugEventFunction, &fn), (wxObject *)NULL),
#endif

LUA_DEBUG_END

#endif
